package com.sunyzc.ebaotech.ybt.simulator.util;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sunyzc.ebaotech.ybt.simulator.IProcessor;
import com.sunyzc.ebaotech.ybt.simulator.ccbnew.CCBNEWProcessor;
import com.sunyzc.ebaotech.ybt.simulator.dgrcb.DGRCBProcessor;
import com.sunyzc.ebaotech.ybt.simulator.icbc.ICBCProcessor;
import com.sunyzc.ebaotech.ybt.simulator.post.POSTProcessor;
import com.sunyzc.ebaotech.ybt.simulator.sdrcb.SDRCBProcessor;

/** 一个巨坑的Util，根据试算、缴费等交易记录生成日结对账批处理模拟报文和文件，慎用！ */
public class YBTUtil {
	private static final Logger log = LoggerFactory.getLogger(YBTUtil.class);

	public static void main(String[] args) throws Exception {
		String requestBodyContentStr = new SDRCBProcessor().generateRequestBodyTemplateStr("8001");
		Matcher dayCheckDetailMatcher = Pattern.compile("<DAYCHECK_DETAILS>([\\w\\W]*</DAYCHECK_DETAIL>)[\\w\\W]*</DAYCHECK_DETAILS>").matcher(requestBodyContentStr); // TODO
		String dayCheckDetailContentStr = "";
		boolean find = dayCheckDetailMatcher.find();
		if (find)
			dayCheckDetailContentStr = dayCheckDetailMatcher.group(1);
		System.out.println(find + ": " + dayCheckDetailContentStr);
	}

	/** 生成模拟银保通日结对账交易的xml内容模板 */
	public static String generateCheckBillXmlTemplateStr(List<IProcessor> processorList, String transType) throws Exception {
		String checkBillXmlTemplateStr = "";
		if (processorList != null && processorList.size() > 0) {
			IProcessor processor0 = processorList.get(0);
			checkBillXmlTemplateStr = processor0.generateRequestBodyTemplateStr(transType);
			Matcher dayCheckXmlDetailMatcher = Pattern.compile("<DAYCHECK_DETAILS>([\\w\\W]*</DAYCHECK_DETAIL>)[\\w\\W]*</DAYCHECK_DETAILS>").matcher(checkBillXmlTemplateStr); // TODO
			StringBuffer dayCheckXmlDetailsContent = new StringBuffer();
			if (dayCheckXmlDetailMatcher.find()) {
				String dayCheckXmlDetailTemplateStr = dayCheckXmlDetailMatcher.group(1); // 获取日结对账模板中单个对账信息节点模板
				checkBillXmlTemplateStr = checkBillXmlTemplateStr.replace(dayCheckXmlDetailTemplateStr, "@DAYCHECK_XML_DETAILS_CONTENT@");
				int effectiveDayCheckIndex = 0; // 只有动态正则替换的节点都是有值的对账信息节点才是有效的
				for (IProcessor processor : processorList) {
					StringBuffer keyElementsValue = new StringBuffer();
					Matcher matcher = Pattern.compile("@((RQ|RP)\\w+-\\w+)@").matcher(dayCheckXmlDetailTemplateStr);
					String dayCheckXmlDetailContentStr = dayCheckXmlDetailTemplateStr;
					effectiveDayCheckIndex++;
					while (matcher.find()) {
						String matcherGroup = matcher.group(1);
						String elementValue = processor.getElementValue(matcherGroup);
						if (elementValue == null || elementValue.equals("")) { // 节点信息不完整的保单不进行对账
							effectiveDayCheckIndex--;
							dayCheckXmlDetailContentStr = "";
							break;
						} else if (dayCheckXmlDetailContentStr.contains("@" + matcherGroup + "@")) {
							if (isNeedDiv100(processor, transType, matcherGroup))
								elementValue = elementValue.contains(".") ? String.format("%.2f", Double.parseDouble(elementValue) / 100) : Long.parseLong(elementValue) / 100 + "";
							dayCheckXmlDetailContentStr = dayCheckXmlDetailContentStr.replace("@" + matcherGroup + "@", elementValue); // 生成单个对账信息节点内容
							keyElementsValue.append(elementValue + ",");
						}
					}
					dayCheckXmlDetailsContent.append(dayCheckXmlDetailContentStr);
					log.info("keyElementsValue: " + keyElementsValue.toString().substring(0, keyElementsValue.length() - 1 < 0 ? 0 : keyElementsValue.length() - 1));
				}
				// 处理总缴费金额部分(<MAIN>中只有一个动态替换标签，也就是缴费金额标签)
				Matcher totalPremiumlMatcher = Pattern.compile("@((RQ|RP)\\w+-\\w+)@").matcher(checkBillXmlTemplateStr);
				if (totalPremiumlMatcher.find()) {
					String premiumStr = processor0.getElementValue(totalPremiumlMatcher.group(1));
					if (isNeedDiv100(processor0, transType, totalPremiumlMatcher.group(1)))
						premiumStr = premiumStr.contains(".") ? String.format("%.2f", Double.parseDouble(premiumStr) / 100) : Long.parseLong(premiumStr) / 100 + "";
					String totalPremiumlStr = premiumStr.contains(".") ? String.format("%.2f", Double.parseDouble(premiumStr) * effectiveDayCheckIndex) : Long.parseLong(premiumStr) * effectiveDayCheckIndex + "";
					checkBillXmlTemplateStr = checkBillXmlTemplateStr.replace("@" + totalPremiumlMatcher.group(1) + "@", totalPremiumlStr);
				}
				checkBillXmlTemplateStr = checkBillXmlTemplateStr.replace("@DAYCHECK_XML_DETAILS_CONTENT@", dayCheckXmlDetailsContent);
			}
		}
		return checkBillXmlTemplateStr;
	}

	/** 生成日结对账文件l内容 */
	public static String generateCheckBillFileContentStr(List<IProcessor> processorList, String transType) throws Exception {
		String NEW_LINE = "\r\n";
		StringBuffer checkBillFileContentStr = new StringBuffer();
		if (processorList != null && processorList.size() > 0) {
			IProcessor processor0 = processorList.get(0);
			if (processor0 instanceof CCBNEWProcessor) {
				// CCBNEW|822|201010101
				checkBillFileContentStr.append("CCBNEW|822|201010101" + NEW_LINE);
				// for (IProcessor processor : processorList) {
				// // P53819152|20161101|jefftoubao20160121001|jefftoubao20160121001|201010101|1019|00001771061908088|1000|
				// checkBillFileContentStr.append("P53819152" + "|");
				// checkBillFileContentStr.append("20161101" + "|");
				// checkBillFileContentStr.append("jefftoubao20160121001" + "|");
				// checkBillFileContentStr.append("jefftoubao20160121001" + "|");
				// checkBillFileContentStr.append("201010101" + "|"); // 银行网点
				// checkBillFileContentStr.append("1019" + "|");
				// checkBillFileContentStr.append("00001771061908088" + "|"); // 保单号
				// checkBillFileContentStr.append("1000" + "|" + NEW_LINE);
				// }
			}
		}
		return checkBillFileContentStr.toString();
	}

	/** 有些银行日结对账的缴费金额需要除以100以将分转换为元 */
	public static boolean isNeedDiv100(IProcessor processor, String transType, String transXmlMapKey) {
		return (processor instanceof ICBCProcessor && "ModalPremAmt".equals(transXmlMapKey.split("-")[1]) && (transType.equals("801") || transType.equals("8001"))) // ICBC
				|| (processor instanceof POSTProcessor && "AMT_PREMIUM".equals(transXmlMapKey.split("-")[1]) && (transType.equals("801") || transType.equals("8001"))) // POST
				|| (processor instanceof DGRCBProcessor && "AMT_PREMIUM".equals(transXmlMapKey.split("-")[1]) && (transType.equals("801") || transType.equals("8001"))); // DGRCB
	}
}
